/* 
 * File:   RepositorioPoller.h
 * Author: maximiliano
 *
 * Created on May 14, 2013, 6:05 PM
 */

#include <stdint.h>
#include <unistd.h>
#include "client_OperacionSincronizacionRepositorio.h"
#include "common_Thread.h"
#include "common_FileUtils.h"
#include "common_Repositorio.h"
#include "common_Mutex.h"
#include "client_IRepositorioPollerManejadorEvento.h"


using namespace TP::Threading;
using namespace TP::Operaciones;

#ifndef REPOSITORIOPOLLER_H
#define	REPOSITORIOPOLLER_H

namespace TP { namespace Archivos {

/**
 * @class Clase encargada de iterar asincronicamente cada cierto intervalo de 
 * tiempo el repositorio fisico de archivos del cliente, detectando posibles 
 * archivos nuevos, modificados o eliminados.
 */
class RepositorioPoller : public Thread {

public:
    
    /**     
     * @param pRepositorio Repositorio contra el cual se comparara, en cada
     * iteracion, el estado actual los archivos fisicos del cliente
     * @param pIntervaloPoleo Intervalo de tiempo, en segundos, entre cada
     * entre cada iteracion del poller.
     */
    RepositorioPoller(Repositorio* pRepositorio, uint32_t pIntervaloPoleo);
    
    void SetRepositorioPollerManejadorEvento (IRepositorioPollerManejadorEvento* pManejadorEventos);
    
    void SetOperacionSincronizacionRepositorio (OperacionSincronizacionRepositorio* pOperacionSincrnizacionRepositorio);
    
    virtual ~RepositorioPoller();

    /**
     * @brief Inicializa el poller antes de comenzar a iterar, validando los
     * parametros de entrada.
     */
    virtual void Iniciar() throw (Excepcion&);
    
    /**
     * @brief Detiene el poller, validando que haya terminado correctamente.
     */
    virtual void Finalizar() throw (Excepcion&);

protected:
    
    /**
     * @brief Metodo principal. Realiza toda la logica de iteracion del poller,
     * detectando los archivos nuevos, modificados o eliminados.
     */
    virtual void tarea ();
    
private:
    
    void setPoleando(const bool pValor);
    
    bool getPoleando();
    
    void evaluarArchivo(const string& pNombreArchivo);
    
    bool esArchivoNuevo(const string &pNombreArchivo);
    
    bool esArchivoModificado(const string &pNombreArchivo);
    
    void notificarArchivoNuevo (const string &pNombreArchivo);
    
    void notificarArchivoModificado (const string &pNombreArchivo);
    
    /**
     * @brief Realiza la logica de deteccion de archivos eliminados en el
     * repositorio fisico del cliente.
     */
    void actualiarEstadoArchivosEliminados ();
    
    bool _poleando;
    Mutex _poleandoMutex;
    Repositorio* _repositorio;
    uint32_t _intervaloPoleo;
    IRepositorioPollerManejadorEvento* manejadorEvento;
    OperacionSincronizacionRepositorio* _operacionSincronizacionRepositorio;
    FileUtils _fileUtils;
};

}}

#endif	/* REPOSITORIOPOLLER_H */

